import pandas as pd
import numpy as np
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')
import plotly.io as pio
pio.templates.default = "plotly_dark"
rfm = pd.read_csv ("rfm_nextstep_export.csv")
rfm.head()
| customer_id | Recency | Frequency | Monetary | |
|---|---|---|---|---|
| 0 | 1 | 102 | 5 | 831.30 |
| 1 | 2 | 34 | 4 | 1840.77 |
| 2 | 3 | 297 | 3 | 136.50 |
| 3 | 4 | 527 | 2 | 349.70 |
| 4 | 5 | 112 | 11 | 2273.00 |
rfm.shape
(1283707, 4)
"""
Scoring suivant une logique de 1 à 5 pour la F et M
et de 5 à 1 pour la R (car il plus il est bas plus vous etes un bon client contrairement aux autres )
"""
rfm['R'] = pd.qcut(rfm['Recency'], 5, labels=[5,4,3,2,1])
rfm['F'] = pd.qcut(rfm['Frequency'].rank(method="first"), 5, labels=[1,2,3,4,5])
rfm['M'] = pd.qcut(rfm['Monetary'], 5, labels=[1,2,3,4,5])
rfm['RFM_Score'] = rfm[['R','F','M']].astype(str).agg(''.join, axis=1)
rfm.head()
| customer_id | Recency | Frequency | Monetary | R | F | M | RFM_Score | |
|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 102 | 5 | 831.30 | 3 | 4 | 4 | 344 |
| 1 | 2 | 34 | 4 | 1840.77 | 5 | 4 | 5 | 545 |
| 2 | 3 | 297 | 3 | 136.50 | 2 | 3 | 2 | 232 |
| 3 | 4 | 527 | 2 | 349.70 | 1 | 2 | 3 | 123 |
| 4 | 5 | 112 | 11 | 2273.00 | 3 | 5 | 5 | 355 |
#Affichage de la distribution des score
fig = px.histogram(rfm, x='RFM_Score', title='Distribution des scores RFM :')
fig.show()
fig.write_image("Distribution_score.png")
"""
Création des segments en fonction de quelques scénarios
simples que nous allons identifier
"""
def segment(score):
r, f, m = int(score[0]), int(score[1]), int(score[2])
# 1. Clients Premium (VIP)
if r >= 4 and f >= 4 and m >= 4:
return "Premium"
# 2. Fidèles actifs
elif r >= 3 and f >= 3:
return "Fidèles"
# 3. Nouveaux ou Récents
elif r >= 4 and f <= 2:
return "Nouveaux"
# 4. À réactiver (anciens fidèles ou gros acheteurs)
elif r <= 2 and (f >= 3 or m >= 4):
return "À Réactiver"
# 5. Perdus ou peu engagés
else:
return "Inactifs"
rfm["segment"] = rfm["RFM_Score"].apply(segment)
rfm.head(10)
| customer_id | Recency | Frequency | Monetary | R | F | M | RFM_Score | segment | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 1 | 102 | 5 | 831.30 | 3 | 4 | 4 | 344 | Fidèles |
| 1 | 2 | 34 | 4 | 1840.77 | 5 | 4 | 5 | 545 | Premium |
| 2 | 3 | 297 | 3 | 136.50 | 2 | 3 | 2 | 232 | À Réactiver |
| 3 | 4 | 527 | 2 | 349.70 | 1 | 2 | 3 | 123 | Inactifs |
| 4 | 5 | 112 | 11 | 2273.00 | 3 | 5 | 5 | 355 | Fidèles |
| 5 | 6 | 6 | 4 | 2199.50 | 5 | 4 | 5 | 545 | Premium |
| 6 | 7 | 112 | 2 | 23.65 | 3 | 2 | 1 | 321 | Inactifs |
| 7 | 8 | 318 | 5 | 458.25 | 2 | 4 | 4 | 244 | À Réactiver |
| 8 | 9 | 557 | 2 | 181.00 | 1 | 2 | 3 | 123 | Inactifs |
| 9 | 10 | 74 | 7 | 296.05 | 5 | 5 | 3 | 553 | Fidèles |
fig = px.pie(rfm, names='segment', title='Répartition des segments :')
fig.show()